-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[libc++][ranges] Ensure range access CPOs are provided in <iterator>
#151745
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc++][ranges] Ensure range access CPOs are provided in <iterator>
#151745
Conversation
@llvm/pr-subscribers-libcxx Author: A. Jiang (frederick-vs-ja) ChangesPer [range.access.general]/1, these CPOs are also provided in Fixes #151698. Drive-by: Add an entry for Full diff: https://github.com/llvm/llvm-project/pull/151745.diff 4 Files Affected:
diff --git a/libcxx/include/iterator b/libcxx/include/iterator
index d25fdfd2a8b33..fc8bdc5e6bcf6 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -737,6 +737,16 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
# include <compare>
# include <concepts>
+// [range.access.general]
+# if _LIBCPP_STD_VER >= 20
+# include <__ranges/access.h>
+# include <__ranges/data.h>
+# include <__ranges/empty.h>
+# include <__ranges/rbegin.h>
+# include <__ranges/rend.h>
+# include <__ranges/size.h>
+# endif
+
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index 96d7a6b897188..b86dd78ecb255 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -405,17 +405,14 @@ namespace std {
# include <__config>
# if _LIBCPP_STD_VER >= 20
-# include <__ranges/access.h>
# include <__ranges/all.h>
# include <__ranges/common_view.h>
# include <__ranges/concepts.h>
# include <__ranges/counted.h>
# include <__ranges/dangling.h>
-# include <__ranges/data.h>
# include <__ranges/drop_view.h>
# include <__ranges/drop_while_view.h>
# include <__ranges/elements_view.h>
-# include <__ranges/empty.h>
# include <__ranges/empty_view.h>
# include <__ranges/enable_borrowed_range.h>
# include <__ranges/enable_view.h>
@@ -423,12 +420,9 @@ namespace std {
# include <__ranges/iota_view.h>
# include <__ranges/join_view.h>
# include <__ranges/lazy_split_view.h>
-# include <__ranges/rbegin.h>
# include <__ranges/ref_view.h>
-# include <__ranges/rend.h>
# include <__ranges/reverse_view.h>
# include <__ranges/single_view.h>
-# include <__ranges/size.h>
# include <__ranges/split_view.h>
# include <__ranges/subrange.h>
# include <__ranges/take_view.h>
@@ -460,7 +454,7 @@ namespace std {
// [ranges.syn]
# include <compare>
# include <initializer_list>
-# include <iterator>
+# include <iterator> // some CPOs are provided in <iterator> per [range.access.general]
// [tuple.helper]
# include <__tuple/tuple_element.h>
diff --git a/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp b/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
index 678483b9b2f2f..49497875dcf95 100644
--- a/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
+++ b/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
@@ -81,6 +81,10 @@ static_assert(test(std::ranges::rend, a));
static_assert(test(std::ranges::size, a));
static_assert(test(std::ranges::ssize, a));
+#if TEST_STD_VER >= 26
+// static_assert(test(std::views::reserve_hint, a));
+#endif
+
// [range.factories]
// views::empty<T> is not a CPO
static_assert(test(std::views::iota, 1));
diff --git a/libcxx/test/std/ranges/range.access/include.iterator.compile.pass.cpp b/libcxx/test/std/ranges/range.access/include.iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..a3c59166eeab0
--- /dev/null
+++ b/libcxx/test/std/ranges/range.access/include.iterator.compile.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// [range.access.general]/1:
+// In addition to being available via inclusion of the <ranges> header, the customization point objects in
+// [range.access] are available when the header <iterator> is included.
+
+#include <iterator>
+#include <type_traits>
+
+#include "test_macros.h"
+
+template <class CPO, class... Args>
+constexpr bool test(CPO& o, Args&&...) {
+ static_assert(std::is_const_v<CPO>);
+ static_assert(std::is_class_v<CPO>);
+ static_assert(std::is_trivially_copyable_v<CPO>);
+ static_assert(std::is_trivially_default_constructible_v<CPO>);
+
+ auto p = o;
+ using T = decltype(p);
+
+ // The type of a customization point object, ignoring cv-qualifiers, shall model semiregular.
+ static_assert(std::semiregular<T>);
+
+ // The type T of a customization point object, ignoring cv-qualifiers, shall model...
+ static_assert(std::invocable<T&, Args...>);
+ static_assert(std::invocable<const T&, Args...>);
+ static_assert(std::invocable<T, Args...>);
+ static_assert(std::invocable<const T, Args...>);
+
+ return true;
+}
+
+int a[10];
+
+static_assert(test(std::ranges::begin, a));
+static_assert(test(std::ranges::end, a));
+static_assert(test(std::ranges::cbegin, a));
+static_assert(test(std::ranges::cdata, a));
+static_assert(test(std::ranges::cend, a));
+static_assert(test(std::ranges::crbegin, a));
+static_assert(test(std::ranges::crend, a));
+static_assert(test(std::ranges::data, a));
+static_assert(test(std::ranges::empty, a));
+static_assert(test(std::ranges::rbegin, a));
+static_assert(test(std::ranges::rend, a));
+static_assert(test(std::ranges::size, a));
+static_assert(test(std::ranges::ssize, a));
+
+#if TEST_STD_VER >= 26
+// static_assert(test(std::views::reserve_hint, a));
+#endif
|
Per [range.access.general]/1, these CPOs are also provided in `<iterator>`. Currently only some of them are provided via transitive inclusion when only `<iterator>` is included. Drive-by: Add an entry for `ranges::reserve_hint` in the general test file for CPOs.
8be6797
to
d73c62f
Compare
libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
Show resolved
Hide resolved
libcxx/test/std/ranges/range.access/include.iterator.compile.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/ranges/range.access/include.iterator.compile.pass.cpp
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with a small comment about ensuring that the CPOs can actually be called.
libcxx/test/std/ranges/range.access/include.iterator.compile.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/ranges/range.access/include.iterator.compile.pass.cpp
Outdated
Show resolved
Hide resolved
static_assert(std::is_trivially_copyable_v<CPO>); | ||
static_assert(std::is_trivially_default_constructible_v<CPO>); | ||
|
||
auto p = o; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auto p = o; | |
auto p = o; | |
(void)o(args...); // to make sure the CPO can actually be used |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, given we actually call CPOs, it perhaps makes more sense to test both compile time and runtime invocability. I'm now changing the test file to .pass.cpp
.
Per [range.access.general]/1, these CPOs are also provided in
<iterator>
. Currently only some of them are provided via transitive inclusion when only<iterator>
is included.Fixes #151698.
Drive-by: Add an entry for
ranges::reserve_hint
in the general test file for CPOs.